/**
 * File AutoSubmittingKeyListener.java
 * ---------------------------------------------------------
 *
 * Copyright (C) 2012 David Bauske (david.bauske@googlemail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * - The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software.
 * - The origin of the software must not be misrepresented.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * TL;DR: As long as you clearly give me credit for this Software, you are free to use as you like, even in commercial
 * software, but don't blame me
 * if it breaks something.
 */
package net.cl.util.ui;

import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JTextField;

/**
 * KeyListener subclass that can be attached to a TextField.
 *
 * When the user types something into the field, a countdown is set off. When it reaches zero and the
 * uuer hasn't typed anything in between, an ActionPerformed event is triggered for the TextField.
 *
 * <p>
 * This is useful for example for search fields to start searching while the user is still typing. The class works on
 * all components subclassing {@link TextField} or {@link JTextField}. The class throws an IllegalArgumentExcption if
 * the parent object is not a subclass of TextField or JTextField.
 * </p>
 *
 * <h3>Example Usage:</h3> <code><pre>JTextField textField = new JTextField();
 * textField.addKeyListener(new AutoSubmittimgKeyListener(300));</pre></code>
 *
 * @author David Bauske
 */
public class AutoSubmittingKeyListener extends KeyAdapter
{
	private long	mSubmitDelay	= 200;
	private long	mLastKeyTyped	= -1;
	private Timer	mFilterTimer	= new Timer();

	/**
	 * Initializes the AutoSubmittimgKeyListener with a typing delay of 200ms.
	 */
	public AutoSubmittingKeyListener()
	{

	}

	/**
	 * Initializes the AutoSubmittimgKeyListener with a specified submit delay.
	 *
	 * @param pSubmitDelay The time in milliseconds the submit should occur after the user stopped typing.
	 */
	public AutoSubmittingKeyListener(long pSubmitDelay)
	{
		this.mSubmitDelay = pSubmitDelay;
	}

	@Override
	public void keyTyped(KeyEvent event)
	{
		mLastKeyTyped = System.currentTimeMillis();

		Object srcObj = event.getComponent();
		if(srcObj instanceof TextField || srcObj instanceof JTextField)
		{
			mFilterTimer.schedule(new SubmitTask(event.getComponent()), mSubmitDelay);
		}
		else
		{
			throw new IllegalArgumentException(
					"AutoSubmittingKeyListener can only be attached to subclasses of java.awt.TextField or javax.swing.JTextField.");
		}
	}

	private class SubmitTask extends TimerTask
	{
		private Object	mSourceObject;

		public SubmitTask(Object pSource)
		{
			this.mSourceObject = pSource;
		}

		@Override
		public void run()
		{
			if(System.currentTimeMillis() - mLastKeyTyped >= mSubmitDelay)
			{
				ActionEvent ae = new ActionEvent(this.mSourceObject,
						ActionEvent.ACTION_PERFORMED, "");

				ActionListener[] actionListeners = null;

				if(this.mSourceObject instanceof TextField)
				{
					actionListeners = ((TextField) this.mSourceObject).getActionListeners();
				}
				else if(this.mSourceObject instanceof JTextField)
				{
					actionListeners = ((JTextField) this.mSourceObject).getActionListeners();
				}
				else
				{
					throw new IllegalArgumentException(
							"AutoSubmittingKeyListener can only be attached to subclasses of java.awt.TextField or javax.swing.JTextField.");
				}

				for(ActionListener al : actionListeners)
				{
					al.actionPerformed(ae);
				}
			}
		}
	}
}
